package co.baiku.boot.common.tools;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * 泛型读取工具
 *
 * @author liyongyao
 */
public class AnnotationTools {
    private AnnotationTools() {
    }

    public static Annotation findClassAnnotation(Class<?> clazz,
                                                 Class<? extends Annotation> ann) {
        if (clazz.isAnnotationPresent(ann)) {
            Annotation s = clazz.getAnnotation(ann);
            return s;
        }
        return null;
    }

    public static Map<Method, ? extends Annotation> findMethodAnnotation(
            Class<?> clazz, Class<? extends Annotation> ann) {
        Map<Method, Annotation> result = new HashMap<Method, Annotation>();
        for (Method m : clazz.getMethods()) {
            for (Annotation annotation : m.getAnnotations()) {
                if (annotation.annotationType() == ann) {
                    result.put(m, annotation);
                }
            }
        }
        return result;
    }

    public static Map<Field, Annotation> findFieldAnnotation(Class<?> clazz,
                                                             Class<? extends Annotation> ann) {
        Map<Field, Annotation> result = new HashMap<Field, Annotation>();
        for (Field field : clazz.getDeclaredFields()) {
            for (Annotation annotation : field.getAnnotations()) {
                if (annotation.annotationType() == ann) {
                    result.put(field, annotation);
                }
            }
        }
        return result;
    }

    public static Map<Field, Annotation> findAllFieldAnnotation(Class<?> clazz,
                                                                Class<? extends Annotation> ann) {
        Map<Field, Annotation> result = new HashMap<Field, Annotation>();
        for (Field field : clazz.getDeclaredFields()) {
            for (Annotation annotation : field.getAnnotations()) {
                if (annotation.annotationType() == ann) {
                    result.put(field, annotation);
                }
            }
        }
        Class<?> superclass = clazz.getSuperclass();
        if (superclass != null) {
            for (Field field : clazz.getSuperclass().getDeclaredFields()) {
                for (Annotation annotation : field.getAnnotations()) {
                    if (annotation.annotationType() == ann) {
                        result.put(field, annotation);
                    }
                }
            }
        }
        return result;
    }

}
